﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using Acme.BookStore2.Permissions;
using Microsoft.AspNetCore.Authorization;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Services;
using Volo.Abp.ObjectExtending;

namespace Acme.BookStore2
{
    [Authorize(BookStore2Permissions.Vehicle.Default)]
    public class VehicleAppService : ApplicationService, IVehicleAppService
    {
        private readonly IVehicleRepository _vehicleRepository;
        private readonly VehicleManager _vehicleManager;

        public VehicleAppService(IVehicleRepository vehicleRepository, VehicleManager vehicleManager)
        {
            _vehicleRepository = vehicleRepository;
            _vehicleManager = vehicleManager;
        }

        public async Task<VehicleDto> GetAsync(Guid id)
        {
            return ObjectMapper.Map<Vehicle, VehicleDto>(await _vehicleRepository.GetAsync(id, false));
        }

        public async Task<PagedResultDto<VehicleDto>> GetPagedListAsync(GetVehiclesInput input)
        {
            var count = await _vehicleRepository.GetCountAsync(input.Number, input.LicensePlateNumber,
                input.IsMaintaining);
            var list = await _vehicleRepository.GetPagedListAsync(input.Sorting, input.MaxResultCount, input.SkipCount,
                input.Number, input.LicensePlateNumber, input.IsMaintaining);

            return new PagedResultDto<VehicleDto>(count, ObjectMapper.Map<List<Vehicle>, List<VehicleDto>>(list));
        }

        [Authorize(BookStore2Permissions.Vehicle.Create)]
        public async Task<VehicleDto> CreateAsync(VehicleCreateDto input)
        {
            var vehicle = new Vehicle(GuidGenerator.Create(), CurrentTenant.Id);

            UpdateVehicle(vehicle, input);
            input.MapExtraPropertiesTo(vehicle);

            await _vehicleManager.CreateAsync(vehicle);
            await CurrentUnitOfWork.SaveChangesAsync();

            return ObjectMapper.Map<Vehicle, VehicleDto>(vehicle);
        }

        [Authorize(BookStore2Permissions.Vehicle.Update)]
        public async Task<VehicleDto> UpdateAsync(Guid id, VehicleUpdateDto input)
        {
            var vehicle = await _vehicleRepository.GetAsync(id);
            vehicle.ConcurrencyStamp = input.ConcurrencyStamp;

            UpdateVehicle(vehicle, input);
            input.MapExtraPropertiesTo(vehicle);

            await _vehicleManager.UpdateAsync(vehicle);
            await CurrentUnitOfWork.SaveChangesAsync();

            return ObjectMapper.Map<Vehicle, VehicleDto>(vehicle);
        }

        [Authorize(BookStore2Permissions.Vehicle.Delete)]
        public async Task DeleteAsync(Guid id)
        {
            var vehicle = await _vehicleRepository.FindAsync(id);
            if (vehicle == null)
            {
                return;
            }

            await _vehicleManager.DeleteAsync(vehicle);
        }

        [Authorize(BookStore2Permissions.Vehicle.Export)]
        public async Task ExportAsync(GetVehiclesInput input)
        {
            input.SkipCount = 0;
            input.MaxResultCount = int.MaxValue;
            var list = (await GetPagedListAsync(input)).Items;

            ISheet sheet;
            using (var stream = new FileStream(@"C:\Users\Administrator\Desktop\车辆调度\TLAX Route Assignment.xlsx",FileMode.Open))
            {
                stream.Position = 0;
                XSSFWorkbook xssfWorkbook = new XSSFWorkbook(stream);
                sheet = xssfWorkbook[0];
                
            }
        }
        
        [Authorize(BookStore2Permissions.Vehicle.Maintenance)]
        public async Task<VehicleDto> SetMaintenanceAsync(Guid id, SetMaintenanceInput input)
        {
            var vehicle = await _vehicleRepository.GetAsync(id);
            vehicle.ConcurrencyStamp = input.ConcurrencyStamp;

            await _vehicleManager.SetMaintenanceAsync(vehicle, input.IsMaintaining);
            await CurrentUnitOfWork.SaveChangesAsync();

            return ObjectMapper.Map<Vehicle, VehicleDto>(vehicle);
        }

        private void UpdateVehicle(Vehicle vehicle, VehicleCreateOrUpdateDtoBase input)
        {
            vehicle.Number = input.Number;
            vehicle.VIN = input.VIN;
            vehicle.LicensePlateNumber = input.LicensePlateNumber;
            vehicle.Brand = input.Brand;
            vehicle.TireType = input.TireType;
            vehicle.VehicleType = input.VehicleType;
            vehicle.Partner = input.Partner;
            vehicle.PurchasingDate = input.PurchasingDate;
            vehicle.VehicleYear = input.VehicleYear;
            vehicle.CostAmount = input.CostAmount;
            vehicle.Cost = input.Cost;
            vehicle.Remark = input.Remark;
            
            ObjectMapper.Map(input.AttachFiles, vehicle.AttachFiles);
        }
    }
}